package com.fc.remoting;

import org.springframework.stereotype.Component;

import com.fc.remoting.handler.HttpServiceHandler;
import com.fc.remoting.logger.RemotingLogger;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

@Component("corenetservice")
public class CoreNetService {
	private EventLoopGroup bossGroup = new NioEventLoopGroup(1);
	private EventLoopGroup workerGroup = new NioEventLoopGroup();
	
	/**
	 * 获取默认的Bootstrap
	 * @return
	 */
	private ServerBootstrap getDefaultServerBootstrap() {
		ServerBootstrap server = new ServerBootstrap();
		server.group(bossGroup, workerGroup)
				.option(ChannelOption.SO_BACKLOG, 1000)
				.option(ChannelOption.TCP_NODELAY, true)
				.channel(NioServerSocketChannel.class)
				.handler(new LoggingHandler(LogLevel.INFO))
				.childOption(ChannelOption.SO_RCVBUF,32*1024)
				.childOption(ChannelOption.SO_SNDBUF,32*1024)
				.childOption(ChannelOption.SO_KEEPALIVE, false);
		return server;
	}
	
	/**
	 * 启动http服务
	 * @param port
	 * @throws Exception
	 */
	public void startHttpServer(int port) throws Exception{
		try{
			ServerBootstrap bootstrap = getDefaultServerBootstrap();
			bootstrap.childHandler(new HttpChannelInitializer()).bind(port).sync();
			
			if (RemotingLogger.getLogger().isInfoEnabled()) {
				RemotingLogger.getLogger().info("服务器启动成功，端口：" + port);
			}
		}catch(Exception e){
			RemotingLogger.getLogger().error(e.getMessage(),e);
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}finally{
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}
	
	/**
	 * 启动TCP服务
	 * @param port
	 * @throws Exception
	 */
	public void startTcpServer(int port) throws Exception{
		try{
			ServerBootstrap bootstrap = getDefaultServerBootstrap();
			bootstrap.childHandler(new TcpChannelInitializer()).bind(port).sync();
		}catch(Exception e){
			RemotingLogger.getLogger().error(e.getMessage(),e);
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}finally{
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}
	
	public void start(int port) throws Exception {
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						public void initChannel(SocketChannel ch) throws Exception {
							// server端发送的是httpResponse，所以要使用HttpResponseEncoder进行编码
							ch.pipeline().addLast("encoder",new HttpResponseEncoder());
							// server端接收到的是httpRequest，所以要使用HttpRequestDecoder进行解码
							ch.pipeline().addLast("decoder",new HttpRequestDecoder());
							ch.pipeline().addLast("handler",new HttpServiceHandler());
							ch.pipeline().addLast("aggregator",new HttpObjectAggregator(1048576));
						}
					}).option(ChannelOption.SO_BACKLOG, 128)
					.childOption(ChannelOption.SO_RCVBUF,64*1024)
					.childOption(ChannelOption.SO_SNDBUF,64*1024)
					.childOption(ChannelOption.SO_KEEPALIVE, false);
			ChannelFuture f = b.bind(port).sync();
			if (RemotingLogger.getLogger().isInfoEnabled()) {
				RemotingLogger.getLogger().info("服务器启动成功，端口:" + port);
			}
			f.channel().closeFuture().sync();
		} finally {
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}
}
